﻿#include "core/event_service.h"
#include "core/async_listener.h"
#include "core/async_listener_impl.h"
#include "core/async_packet_socket_impl.h"

namespace vz {

std::map<Thread*, EventService::Ptr> EventService::event_services_;

EventService::Ptr EventService::GetCurrentEventService() {
  Thread *thread = Thread::Current();
  std::map<Thread*, EventService::Ptr>::iterator iter =
    event_services_.find(thread);
  if (iter == event_services_.end()) {
    EventService::Ptr event_service(
      new RefCountedObject<EventService>(thread));
    event_services_.insert(std::make_pair(thread, event_service));
    return event_service;
  } else {
    return iter->second;
  }
}

EventService::Ptr EventService::CreateEventService() {
  Thread *thread = new Thread();
  thread->Start();
  EventService::Ptr event_service(
    new RefCountedObject<EventService>(thread));
  event_services_.insert(std::make_pair(thread, event_service));
  return event_service;
}

EventService::EventService(Thread* thread)
  : thread_(thread) {
}

EventService::~EventService() {
}

EventService::Ptr EventService::SharedFromThis() {
  return EventService::Ptr(this);
}

void EventService::Post(MessageHandler *phandler,
                        uint32 id/* = 0*/,
                        MessageData *pdata/* = NULL*/,
                        bool time_sensitive/* = false*/) {
  thread_->Post(phandler, id, pdata, time_sensitive);
}

void EventService::PostDelayed(int cmsDelay,
                               MessageHandler *phandler,
                               uint32 id/* = 0*/,
                               MessageData *pdata/* = NULL*/) {
  thread_->PostDelayed(cmsDelay, phandler, id, pdata);
}

void EventService::PostAt(uint32 tstamp,
                          MessageHandler *phandler,
                          uint32 id/* = 0*/,
                          MessageData *pdata/* = NULL*/) {
  thread_->PostAt(tstamp, phandler, id, pdata);
}

AsyncListener::Ptr EventService::CreateListener() {
  SocketServer* socket_server = thread_->socketserver();
  if (!socket_server) {
    LOG(LS_ERROR) << "socket server is null!";
    return NULL;
  }

  AsyncSocket* socket = socket_server->CreateAsyncSocket(SOCK_STREAM);
  if (!socket) {
    LOG(LS_ERROR) << "create socket failed!";
    return NULL;
  }

  return new RefCountedObject<AsyncListenerImpl>(socket);
}

AsyncPacketSocket::Ptr EventService::CreateSocket() {
  SocketServer* socket_server = thread_->socketserver();
  if (!socket_server) {
    LOG(LS_ERROR) << "socket server is null!";
    return NULL;
  }

  AsyncSocket* socket = socket_server->CreateAsyncSocket(SOCK_STREAM);
  if (!socket) {
    LOG(LS_ERROR) << "create socket failed!";
    return NULL;
  }

  return new RefCountedObject<AsyncPacketSocketImpl>(socket);
}

void EventService::Run() {
  thread_->Run();
}

void EventService::Quit() {
  thread_->Quit();
}

}  // namespace vz

